/**
 * 
 */
package denaris.core;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;

import denaris.core.entity.Collectible;
import denaris.core.entity.Player;
import denaris.factory.ImageFactory;
import denaris.midlet.DenarisGameCanvas;
import denaris.midlet.GameScreen;
import denaris.midlet.DenarisGameCanvas.DisplayProperties;

/**
 * @author stkl23
 * 
 */
public class Statusbar {
	public static Image statusbar = ImageFactory
			.getImage("/denaris/resource/image/statusbar.png");

	public static Image digits = ImageFactory.getImage("/denaris/resource/image/digits_small.png");
	public static Image shotLevels = ImageFactory.getImage("/denaris/resource/image/shot_levels.png");
	public static Image missileLevels = ImageFactory.getImage("/denaris/resource/image/missile_levels.png");
	public static Image shieldLevels = ImageFactory.getImage("/denaris/resource/image/shield_levels.png");
	
	private static Statusbar instance;
	
	private int x_red = 0;

	private int x_green = 0;

	private int x_blue = 0;

	private int y_all = 0;
	
	private int y_digit = 0;
	
	private int y_icons = 0;
	
	private int collectibleWidth = 0;
	
	private int collectibleSpacing = 0;
	
	public void doFullRepaint(Graphics buffer) {
		buffer.setClip(0, 0, DisplayProperties.DISPLAY_WIDTH, DisplayProperties.DISPLAY_HEIGHT);
		// we must calculate the width of the three collectible sections (red,
		// green and blue)
		int minWidth = statusbar.getWidth(); // in this case all three
												// sections are just one pixel
												// wide (inacceptable)
		// there are already 3 pixels of the collectible sections within the
		// minWidth value - those must be taken out of the average value
		// calculation
		minWidth -= 3;
		// calculate the average width
		int avgWidth = (DisplayProperties.DISPLAY_WIDTH - minWidth) / 3;
		int avgWidthMod = (DisplayProperties.DISPLAY_WIDTH - minWidth) % 3;
		int y_dest = DisplayProperties.GAME_TOP + DisplayProperties.GAME_HEIGHT;
		y_all = y_dest + 9;
		y_digit = y_dest + 6;
		y_icons = y_dest + 5;
		collectibleWidth = avgWidth / 6;
		if (collectibleWidth >= 4) {
			collectibleWidth -= 2;
			collectibleSpacing = 2;			
		}else if (collectibleWidth < 4 && collectibleWidth >= 2){
			collectibleWidth -= 1;
			collectibleSpacing = 1;
		}
		
		// copy the first section (static)
		buffer.drawRegion(statusbar, 0, 0, 57, 18, 0, 0, y_dest, Graphics.TOP
				| Graphics.LEFT);
		// now generate the three dynamically sized sections
		int x = 0;
		x_red = 57;
		x_green = 80 + avgWidth;
		x_blue = 103 + (avgWidth << 1);
		for (x = 0; x < avgWidth + avgWidthMod; x++) {
			buffer.drawRegion(statusbar, 57, 0, 1, 18, 0, x_red + x, y_dest,
					Graphics.TOP | Graphics.LEFT);
			buffer.drawRegion(statusbar, 57, 0, 1, 18, 0, x_green + x, y_dest,
					Graphics.TOP | Graphics.LEFT);
			buffer.drawRegion(statusbar, 57, 0, 1, 18, 0, x_blue + x, y_dest,
					Graphics.TOP | Graphics.LEFT);
		}
		// copy the rest of the sections
		buffer.drawRegion(statusbar, 58, 0, 23, 18, 0, x_red + avgWidth, y_dest,
				Graphics.TOP | Graphics.LEFT);
		buffer.drawRegion(statusbar, 82, 0, 23, 18, 0, x_green + avgWidth, y_dest,
				Graphics.TOP | Graphics.LEFT);
		buffer.drawRegion(statusbar, 106, 0, 8, 18, 0, x_blue + avgWidth
				+ avgWidthMod, y_dest, Graphics.TOP | Graphics.LEFT);

		// generate the beam indicator
		int y_beam = y_dest + 19;
		buffer.drawRegion(statusbar, 0, 19, 40, 7, 0, 0, y_beam, Graphics.TOP | Graphics.LEFT);
		// the progressbar in the middle also has a dynamic width
		int progressWidth = DisplayProperties.DISPLAY_WIDTH - 80;
		for (x = 0; x < progressWidth; x++) {
			buffer.drawRegion(statusbar, 40, 19, 1, 7, 0, x + 40, y_beam, Graphics.TOP | Graphics.LEFT);
		}
		x = 0;
		for (int i=0; i <= progressWidth / 6; i++) {
			buffer.drawRegion(statusbar, 41, 21, 3, 4, 0, x + 41, y_beam + 2, Graphics.TOP | Graphics.LEFT);
			x+=6;
		}
		buffer.drawRegion(statusbar, 0, 19, 40, 7, Sprite.TRANS_MIRROR, DisplayProperties.DISPLAY_WIDTH, y_beam, Graphics.TOP | Graphics.RIGHT);
		
		Player player = GameScreen.getInstance().getPlayer();
		// draw the lives
		drawLives(buffer, player.getLifeCount());
		// draw the status of the collectibles
		redrawCollectibles(buffer, Collectible.COLLECTIBLE_SHOT, player.getShotCount());
		redrawCollectibles(buffer, Collectible.COLLECTIBLE_MISSILES, player.getMissileCount());
		redrawCollectibles(buffer, Collectible.COLLECTIBLE_SHIELD, player.getShieldCount());
	}

	public int getHeight() {
		return statusbar.getHeight();
	}
	
	public void redrawCollectibles(Graphics buffer, int type, int count) {
		int xStart = 0;
		int color = 0xFF0000;
		Image img = null;
		switch (type) {
		case Collectible.COLLECTIBLE_SHOT:{
			xStart = x_red;
			color = 0xFF0000;
			img = shotLevels;
			break;
		}
		case Collectible.COLLECTIBLE_MISSILES:{
			xStart = x_green;
			color = 0x00FF00;
			img = missileLevels;
			break;
		}
		case Collectible.COLLECTIBLE_SHIELD:{
			xStart = x_blue;
			color = 0x0000FF;
			img = shieldLevels;
			break;
		}
		}
		// save clipping information
		DenarisGameCanvas.getInstance().saveCurrentClipping();
		// clear the collectible area;
		buffer.setClip(0, DisplayProperties.GAME_TOP + DisplayProperties.GAME_HEIGHT, DisplayProperties.DISPLAY_WIDTH, getHeight());
		buffer.setColor(0);
		buffer.fillRect(xStart, y_all, (collectibleWidth + collectibleSpacing) * 6,  2);
		// we need the level of the collectible type. A new level is reached with every 7th collected item
		count -= 1;
		int level = count / 6; //
		// draw the icon
		buffer.drawRegion(img, level * 10, 0, 10, 10, 0, xStart-15, y_icons, Graphics.LEFT|Graphics.TOP);
		// draw the collectibles
		buffer.setColor(color);
		if (count >= 0) {
			for (int i=0; i<=(count % 6); i++) {
				buffer.fillRect(xStart, y_all, collectibleWidth, 2);
				xStart += collectibleWidth + collectibleSpacing;
			}
		}
		DenarisGameCanvas.getInstance().restoreClipping();
	}

	public void drawLives(Graphics buffer, int lifeCount) {
		int x = 27;
		int n = lifeCount / 10;
		// save the clipping rectangle information
		DenarisGameCanvas.getInstance().saveCurrentClipping();
		buffer.setClip(0, 0, DisplayProperties.DISPLAY_WIDTH, DisplayProperties.DISPLAY_HEIGHT);
		buffer.drawRegion(digits, n * 5, 0, 5, 8, 0, x, y_digit, Graphics.TOP|Graphics.LEFT);
		n = lifeCount % 10;
		x += 5;
		buffer.drawRegion(digits, n * 5, 0, 5, 8, 0, x, y_digit, Graphics.TOP|Graphics.LEFT);
		// restore the old clipping rectangle
		DenarisGameCanvas.getInstance().restoreClipping();
	}

	public static Statusbar getInstance() {
		if (instance == null) {
			instance = new Statusbar();
		}
		return instance;
	}
}
